#include <stdio.h>
#include <stdlib.h>
//#include "net_common.h"
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include <string.h>
#include <unistd.h>
 
#include "http_client.h"
 
#define BUFFER_SIZE 1024
//#define HTTP_POST "POST /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n"\
//	"Content-Type:application/x-www-form-urlencoded\r\nContent-Length:\
//	%d\r\n\r\n%s"

#define HTTP_POST "POST /%s HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n%s"

//#define HTTP_POST "POST /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n"\
//	"Content-Length:%d\r\n\r\n%s"


#define HTTP_GET "GET /%s HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*%s\r\n\r\n"
 
 
static int http_tcpclient_create(const char *host, int port)
{
	struct hostent *he;
	struct sockaddr_in server_addr; 
	int socket_fd;
 
	if ((he = gethostbyname(host)) == NULL) {
        printf("can't find addr of host %s\n",host);
		return -1;
	}
	if (he->h_addr_list == NULL) {
        printf("addr_list of hostent is NULL\n");
		return -1;
	}
	if (he->h_addr_list[0] == NULL) {
        printf("addr_list[0] of hostent is NULL\n");
		return -1;
	}
 
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);
	//server_addr.sin_addr = *((struct in_addr *)he->h_addr);
	//printf("<%d>,<%s>",he->h_addrtype,inet_ntoa(*(struct in_addr *)he->h_addr_list[0]));
 	if(inet_pton(he->h_addrtype, inet_ntoa(*(struct in_addr *)he->h_addr_list[0]), &server_addr.sin_addr) <= 0){
        printf("inet_pton -2\n");
		return -2;
	}
	if ((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == (-1)) {
        printf("socket -3\n");
		return -3;
	}
 
	if (connect(socket_fd,
		(struct sockaddr *)&server_addr,
		sizeof(struct sockaddr)) == -1) {
		return -4;
	}
 
	return socket_fd;
}





static void http_tcpclient_close(int socket)
{
	close(socket);
}





static int http_parse_url(const char *url, char *host, char *file, int *port)
{
	char *ptr1, *ptr2;
	int len = 0;
	if (!url || !host || !file || !port) {
		return -1;
	}
 
	ptr1 = (char *)url;
 
	if (!strncmp(ptr1, "http://", strlen("http://"))) {
		ptr1 += strlen("http://");
		*port = 80;
	}else if(!strncmp(ptr1, "https://", strlen("https://"))){
		ptr1 += strlen("https://");
		*port = 443;
		
	} else {
		return -1;
	}
 
	ptr2 = strchr(ptr1, '/');
	if (ptr2) {
		len = strlen(ptr1) - strlen(ptr2);
		memcpy(host, ptr1, len);
		host[len] = '\0';
		if (*(ptr2 + 1)) {
			memcpy(file,ptr2 + 1,strlen(ptr2) - 1 );
			file[strlen(ptr2) - 1] = '\0';
		}
	} else {
		memcpy(host,ptr1,strlen(ptr1));
		host[strlen(ptr1)] = '\0';
	}
	ptr1 = strchr(host,':');
	if (ptr1) {
		*ptr1++ = '\0';
		*port = atoi(ptr1);
	} else {
		*port = MY_HTTP_DEFAULT_PORT;
	}
 
	return 0;
}






static int http_tcpclient_recv(int socket, char *lpbuff)
{
	int recvnum = 0;
 
	recvnum = recv(socket, lpbuff, BUFFER_SIZE*4, 0);
 
	return recvnum;
}





static int http_tcpclient_send(int socket, char *buff, int size)
{
	int sent=0, tmpres=0;
 
	while (sent < size) {
		tmpres = send(socket, buff+sent, size-sent, 0);
		if(tmpres == -1){
			return -1;
		}
		sent += tmpres;
	}
	return sent;
}






static char *http_parse_result(const char*lpbuf)
{
#if 0
	printf("----------------------------------------------------\r\n");
	printf("<");
	int cnt=0;
	while(lpbuf[cnt]){
		printf("%c",lpbuf[cnt++]);
	}
	printf(">\r\n");
	printf("----------------------------------------------------\r\n");
#endif	
	char *ptmp = NULL; 
	char *response = NULL;
	if(lpbuf == NULL){
		return NULL;
	}
	ptmp = (char*)strstr(lpbuf, "HTTP/1.1");
	if (!ptmp) {
		printf("http/1.1 not faind\n");
		return NULL;
	}
	
	if (atoi(ptmp + 9) != 200){
		printf("result:\n%s\n", lpbuf);
		return NULL;
	}
 	
	ptmp = (char *)strstr(lpbuf, "\r\n\r\n");
	if (!ptmp) {
		printf("ptmp is NULL\n");
		return NULL;
	}
	
	response = (char *)malloc(strlen(ptmp) + 1);
	
	if (!response) {
		printf("malloc failed \n");
		return NULL;
	}
	memset(response,0,strlen(ptmp) + 1);
	strncpy(response, ptmp+4,strlen(ptmp+4));
#if 0
	printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n");
	printf("<");
	cnt=0;
	while(ptmp[4+cnt]){
		printf("%c",ptmp[4+cnt]);
		cnt++;
	}
	printf(">\r\n");
	printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n");
#endif
#if 0
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n");
	printf("<");
	cnt=0;
	while(response[cnt]){
		printf("%c",response[cnt]);
		cnt++;
	}
	printf(">\r\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n");
#endif	
	
	//printf("----------------------------------------------------\r\n");
	return response;
}






char *http_post(const char *url, const char *post_str,const char *content_type)
{
 
	int socket_fd = -1;
	char *lpbuf = NULL;
	
	char *host_addr = NULL; 
	char *file =NULL;  
	lpbuf = malloc(BUFFER_SIZE*4);
	if(lpbuf == NULL){		
		return NULL;
	}
	host_addr = malloc(256);
	if(host_addr == NULL){	
		free(lpbuf);
		return NULL;
	}
	file = malloc(256);
	if(file==NULL){
		free(lpbuf);
		free(host_addr);
		return NULL;
	}
	memset(lpbuf,0,BUFFER_SIZE*4);
	memset(file,0,256);
	memset(host_addr,0,256);
	int port = 0;
	if (!url) {
		printf("failed!\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
	if (http_parse_url(url, host_addr, file, &port)) {
		printf("http_parse_url failed!\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
	socket_fd = http_tcpclient_create(host_addr, port);
	if (socket_fd < 0) {
		printf("http_tcpclient_create failed %d\n",socket_fd);
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
	printf("post:%s %s\n",file,post_str);
	sprintf(lpbuf,
		HTTP_POST,
		file,
		host_addr,
		port,
		content_type,
		(int)strlen(post_str),
		post_str);
	if (http_tcpclient_send(socket_fd, lpbuf, strlen(lpbuf)) < 0) {
		printf("http_tcpclient_send failed..\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
	/* it's time to recv from server */
	if (http_tcpclient_recv(socket_fd,lpbuf) <= 0) {
		printf("http_tcpclient_recv failed\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}	
	http_tcpclient_close(socket_fd);
	char *resoult_str = http_parse_result(lpbuf);
	free(lpbuf);
	free(file);
	free(host_addr);
	return resoult_str;
}







char *http_get(const char *url,const char *content_type)
{
	int socket_fd = -1;
	char *lpbuf = NULL;
	char *host_addr = NULL; 
	char *file =NULL;  
	lpbuf = malloc(BUFFER_SIZE*4);
	if(lpbuf == NULL){		
		return NULL;
	}
	host_addr = malloc(256);
	if(host_addr == NULL){	
		free(lpbuf);
		return NULL;
	}
	file = malloc(256);
	if(file==NULL){
		free(lpbuf);
		free(host_addr);
		return NULL;
	}
	memset(lpbuf,0,BUFFER_SIZE*4);
	memset(file,0,256);
	memset(host_addr,0,256);
	int port = 0;
 
	if (!url) {
		printf("failed!\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
 
	if (http_parse_url(url,host_addr,file,&port)) {
		printf("http_parse_url failed!\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
 	
	socket_fd = http_tcpclient_create(host_addr,port);
	if (socket_fd < 0) {
		printf("http_tcpclient_create failed:%s : %d - %s\n",host_addr,port,url);
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
 	
	sprintf(lpbuf,HTTP_GET,file,host_addr,port,content_type);
 
	if (http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf)) < 0) {
		printf("http_tcpclient_send failed..\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
	
 	memset(lpbuf,0,BUFFER_SIZE*4);
	if (http_tcpclient_recv(socket_fd,lpbuf) <= 0) {
		printf("http_tcpclient_recv failed\n");
		free(lpbuf);
		free(file);
		free(host_addr);
		return NULL;
	}
	
	http_tcpclient_close(socket_fd);

	
 	char *resoult_str = http_parse_result(lpbuf);
	free(lpbuf);
	free(file);
	free(host_addr);
	return resoult_str;
}
 





 
 

